package com.wkh.project.service.aspect;

import com.wkh.project.common.result.ResultCodeEnum;
import com.wkh.project.common.util.AuthContextHolder;
import com.wkh.project.service.annotation.LoginCheck;
import com.wkh.project.service.constant.RedisConstant;
import com.wkh.project.service.execption.GuiguException;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author wangkehua
 * 切面类
 */
@Component
@Aspect
public class LoginCheckAnnotation {
    @Resource
    private RedisTemplate redisTemplate;
    //定义一个环绕通知，进行登录校验
    @Around("execution(* com.wkh.project.*.controller.*.*(..)) && @annotation(loginCheck)")
    public Object loginCheck(ProceedingJoinPoint proceedingJoinPoint,LoginCheck loginCheck) throws Throwable {
        //1.获取request对象
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
        if (attributes == null) {
            throw new GuiguException(ResultCodeEnum.SERVICE_ERROR);
        }
        HttpServletRequest request = attributes.getRequest();
        //2.从request中拿到token
        String token = request.getHeader("token");
        if (StringUtils.isBlank(token)){
            throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
        }
        //3.拿到token后到redis中查询用户id
        String customerId = (String) redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
        if (StringUtils.isBlank(customerId)){
            throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
        }
        //4.把用户id放到ThreadLocal中
        if (StringUtils.isNotBlank(customerId)){
            AuthContextHolder.setUserId(Long.valueOf(customerId));
        }
        //5.执行业务逻辑
        return proceedingJoinPoint.proceed();
    }
}
